﻿/**************************************************************
 *
 * 唯一标识：1dad0b24-9f2f-406a-bedf-0ba5e8a24642
 * 命名空间：Sgr.UPMS.API.Controllers
 * 创建时间：2024/1/1
 * 描述：用户控制器
 *
 **************************************************************/

using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Sgr.Application.ViewModels;
using Sgr.AspNetCore.ActionFilters.AuditLogs;
using Sgr.AspNetCore.ActionFilters.Permissions;
using Sgr.UPMS.Application.Commands.Users;
using Sgr.UPMS.Application.Queries;
using Sgr.UPMS.Application.ViewModels;

namespace Sgr.UPMS.Controllers
{
    /// <summary>
    /// 用户管理接口
    /// </summary>
    [Route("api/v1/sgr/users")]
    [ApiController]
    [Produces("application/json")]
    [Tags("User")]
    public class UserController : ControllerBase
    {
        private readonly IMediator _mediator;
        private readonly IUserQueries _userQueries;

        /// <summary>
        /// 初始化用户管理控制器
        /// </summary>
        public UserController(IMediator mediator,
            IUserQueries userQueries)
        {
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
            _userQueries = userQueries ?? throw new ArgumentNullException(nameof(userQueries));
        }

        #region Command

        /// <summary>
        /// 创建用户账号
        /// </summary>
        /// <param name="command">创建用户的请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/users
        ///     {
        ///         "loginName": "zhangsan",
        ///         "loginPassword": "password123",
        ///         "userName": "张三",
        ///         "departmentId": 1,
        ///         "primaryDutyId": 1,
        ///         "dutyIds": [1, 2],
        ///         "roleIds": [1],
        ///         "orgId": 1
        ///     }
        /// </remarks>
        /// <response code="200">创建成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(Permissions.CreateUser)]
        [HttpPost]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("创建用户账号", false)]
        public async Task<ActionResult<bool>> CreateAsync([FromBody] CreateUserCommand command, System.Threading.CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 更新用户账号信息
        /// </summary>
        /// <param name="command">更新用户的请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <response code="200">更新成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(Permissions.UpdateUser)]
        [HttpPut]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("更新用户账号")]
        public async Task<ActionResult<bool>> UpdateAsync([FromBody] UpdateUserCommand command, System.Threading.CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 删除用户账号
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="checkToken">安全校验令牌</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <response code="200">删除成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(Permissions.DeleteUser)]
        [HttpDelete("{id:long:min(1)}")]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("删除用户账号")]
        public async Task<ActionResult<bool>> DeleteAsync(
            [FromRoute] long id,
            [FromQuery(Name = "check_token")] string checkToken,
            System.Threading.CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(new DeleteUserCommand { UserId = id, TemporaryToken = checkToken }, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 更新用户账号状态
        /// </summary>
        /// <param name="command">更新状态的请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/users/status
        ///     {
        ///         "userId": 1,
        ///         "state": "Normal"
        ///     }
        /// </remarks>
        /// <response code="200">更新成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(Permissions.ModifyUserStatus)]
        [HttpPost("change-status")]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("更新用户状态")]
        public async Task<ActionResult<bool>> UpdateStatusAsync([FromBody] ModifyUserStatusCommand command, System.Threading.CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 重置用户密码
        /// </summary>
        /// <param name="command">重置密码的请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/users/password/reset
        ///     {
        ///         "userId": 1,
        ///         "password": "newpassword123"
        ///     }
        /// </remarks>
        /// <response code="200">重置成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(Permissions.ResetPassword)]
        [HttpPost("password/reset")]
        [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
        [AuditLogActionFilter("重置用户密码")]
        public async Task<ActionResult<string>> ResetPasswordAsync([FromBody] ResetPasswordCommand command, System.Threading.CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return (!result.IsSuccess || string.IsNullOrEmpty(result.Data)) ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="command">注册请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/users/register
        ///     {
        ///         "orgInvitationCode": "ABC123",
        ///         "authenticationType": "PhoneNumber",
        ///         "account": "13800138000",
        ///         "verificationCode": "123456",
        ///         "loginPassword": "Password123!@#",
        ///         "userName": "张三"
        ///     }
        /// </remarks>
        /// <response code="200">注册成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [HttpPost("register")]
        [AllowAnonymous]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("用户注册", false)]
        public async Task<ActionResult<bool>> RegisterAsync([FromBody] RegisterUserCommand command, System.Threading.CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess ?
                this.CustomBadRequest(result.Message ?? "注册失败") :
                Ok(result.Data);
        }

        #endregion Command

        #region Query

        /// <summary>
        /// 获取用户详情
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <response code="200">获取成功</response>
        /// <response code="401">未经授权的访问</response>
        /// <response code="404">指定的用户不存在</response>
        [CheckPermission(Permissions.ViewUser)]
        [HttpGet("{id:long:min(0)}")]
        [ProducesResponseType(typeof(OutUserViewModel), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        [AuditLogActionFilter("获取用户详情")]
        public async Task<ActionResult<OutUserViewModel>> GetByIdAsync([FromRoute] long id, System.Threading.CancellationToken cancellationToken)
        {
            var result = await _userQueries.GetByIdAsync(id, cancellationToken);
            return result == null ? NotFound() : Ok(result);
        }

        /// <summary>
        /// 查询用户列表
        /// </summary>
        /// <param name="request">查询条件</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/users/search
        ///     {
        ///         "orgId": 1,
        ///         "departmentId": 1,
        ///         "loginName": "zhang",
        ///         "state": "Normal",
        ///         "pageIndex": 1,
        ///         "pageSize": 10
        ///     }
        /// </remarks>
        /// <response code="200">查询成功</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(Permissions.ViewUser)]
        [HttpPost("search")]
        [ProducesResponseType(typeof(PagedResponse<OutUserViewModel>), StatusCodes.Status200OK)]
        [AuditLogActionFilter("查询用户列表")]
        public async Task<ActionResult<PagedResponse<OutUserViewModel>>> SearchAsync([FromBody] InUserSearchModel request, System.Threading.CancellationToken cancellationToken)
        {
            return Ok(await _userQueries.GetPagedListAsync(request, cancellationToken));
        }

        /// <summary>
        /// 根据组织ID获取管理员账号信息
        /// </summary>
        /// <param name="orgId">组织ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <response code="200">获取成功</response>
        /// <response code="401">未经授权的访问</response>
        /// <response code="404">未找到管理员账号</response>
        [CheckPermission]
        [HttpGet("admin/{orgId:long:min(1)}")]
        [ProducesResponseType(typeof(OutUserViewModel), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        [AuditLogActionFilter("获取组织管理员账号信息")]
        public async Task<ActionResult<OutUserViewModel>> GetAdminByOrgIdAsync([FromRoute] long orgId, System.Threading.CancellationToken cancellationToken)
        {
            var result = await _userQueries.GetAdminByOrgIdAsync(orgId, cancellationToken);
            return result == null ? NotFound() : Ok(result);
        }

        #endregion Query
    }
}